/**
 * Background - 背景实体类
 * 处理背景图像的渲染和滚动效果
 */

import { Entity, EntityType, type EntityOptions } from './Entity'


export interface BackgroundOptions extends Omit<EntityOptions, 'type'> {
  /** 滚动速度 */
  scrollSpeed: number
  /** 是否重复滚动 */
  repeat: boolean
  /** 视差层级（数值越大，滚动越慢） */
  parallaxLayer: number
  /** 透明度 */
  opacity?: number
}

/**
 * 背景实体类
 * 支持水平滚动和视差效果
 */
export class Background extends Entity {
  public scrollSpeed: number
  public repeat: boolean
  public parallaxLayer: number
  public opacity: number
  private originalX: number

  constructor(options: BackgroundOptions) {
    super({
      ...options,
      type: EntityType.BACKGROUND
    })

    this.scrollSpeed = options.scrollSpeed
    this.repeat = options.repeat
    this.parallaxLayer = Math.max(1, options.parallaxLayer)
    this.opacity = options.opacity ?? 1.0
    this.originalX = this.x
  }

  /**
   * 更新背景位置
   * @param deltaTime 距离上一帧的时间差（毫秒）
   */
  update(deltaTime: number): void {
    if (!this.active) return

    const deltaSeconds = deltaTime / 1000
    const actualScrollSpeed = this.scrollSpeed / this.parallaxLayer

    // 更新水平位置
    this.x -= actualScrollSpeed * deltaSeconds

    // 如果启用重复滚动，当背景完全移出屏幕时重置位置
    if (this.repeat && this.x + this.width <= 0) {
      this.x = this.originalX
    }
  }

  /**
   * 渲染背景
   * @param ctx Canvas渲染上下文
   */
  render(ctx: CanvasRenderingContext2D): void {
    if (!this.visible) return

    // 保存当前透明度
    const originalAlpha = ctx.globalAlpha
    ctx.globalAlpha = this.opacity

    if (this.repeat) {
      this.renderRepeating(ctx)
    } else {
      super.render(ctx)
    }

    // 恢复透明度
    ctx.globalAlpha = originalAlpha
  }

  /**
   * 渲染重复背景
   */
  private renderRepeating(ctx: CanvasRenderingContext2D): void {
    const canvasWidth = ctx.canvas.width
    let currentX = this.x

    // 确保背景完全覆盖屏幕
    while (currentX < canvasWidth) {
      if (this.sprite && this.sprite.image) {
        this.renderSpriteAt(ctx, currentX)
      } else {
        this.renderDefaultAt(ctx, currentX)
      }
      currentX += this.width
    }
  }

  /**
   * 在指定位置渲染精灵
   */
  private renderSpriteAt(ctx: CanvasRenderingContext2D, x: number): void {
    if (!this.sprite?.image) return

    const sprite = this.sprite
    const image = sprite.image! // 我们已经检查了image存在
    
    if (sprite.frameWidth && sprite.frameHeight) {
      ctx.drawImage(
        image,
        sprite.frameX || 0,
        sprite.frameY || 0,
        sprite.frameWidth,
        sprite.frameHeight,
        x,
        this.y,
        this.width,
        this.height
      )
    } else {
      ctx.drawImage(
        image,
        x,
        this.y,
        this.width,
        this.height
      )
    }
  }

  /**
   * 在指定位置渲染默认背景
   */
  private renderDefaultAt(ctx: CanvasRenderingContext2D, x: number): void {
    ctx.fillStyle = this.getDefaultColor()
    ctx.fillRect(x, this.y, this.width, this.height)
  }

  /**
   * 重置背景位置
   */
  reset(): void {
    this.x = this.originalX
  }

  /**
   * 设置滚动速度
   */
  setScrollSpeed(speed: number): void {
    this.scrollSpeed = speed
  }

  /**
   * 设置透明度
   */
  setOpacity(opacity: number): void {
    this.opacity = Math.max(0, Math.min(1, opacity))
  }

  /**
   * 设置视差层级
   */
  setParallaxLayer(layer: number): void {
    this.parallaxLayer = Math.max(1, layer)
  }
}